package io.openmessaging.map;

import io.openmessaging.Conf;
import io.openmessaging.utils.Assert;

import java.lang.reflect.Array;
import java.util.function.Supplier;

/**
 * 相当于 topicId、queueId 的联合索引
 * 对比多重HashMap，更节省内存，插入和搜索效率更高
 */
public class TopicQueueMap<E> {
    private final E[][] topics;

    public TopicQueueMap(Class<E> eClass) {
        //topic总数<=100 每个topic有N个queueId（1 <= N <= 5,000）
        this.topics = (E[][]) Array.newInstance(eClass, Conf.maxTopicId, Conf.maxQueueId);
    }

    public E set(int topicId, int queueId, E e) {
        Assert.isTrue(topicId < Conf.maxTopicId, "topicId 过大：", topicId);
        Assert.isTrue(queueId < Conf.maxQueueId, "queueId 过大：", queueId);

        topics[topicId][queueId] = e;
        return e;
    }

    public E get(int topicId, int queueId) {
        if (topicId >= topics.length || queueId >= topics[0].length)
            return null;

        return topics[topicId][queueId];
    }

    /**
     * 每个队列只有一个线程处理，不存在并发
     */
    public E computeIfAbsent(int topicId, int queueId, Supplier<E> supplier) {
        E e = topics[topicId][queueId];
        if (e == null) {
            topics[topicId][queueId] = (e = supplier.get());
        }
        return e;
    }
}
